/*
* Copyright (C) 2021, KylinSoft Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/&gt;.
*
*/

#include "mainwidget.h"
#define cimg_use_jpeg

#include <QMessageBox>
#include <QWidgetList>
#include <QPropertyAnimation>
#include <QTimer>
#include <kysdk/applications/gsettingmonitor.h>
#include "Qt/windowmanage.hpp"
#include <kysdk/applications/usermanual.h>
#include <KWindowEffects>
#include <kysdk/kysdk-system/libkylockscreen.h>
#include "usb.h"
#include <CImg.h>

int const MainWidget::EXIT_CODE_REBOOT = -123456789;

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent),
      m_titleBar(new TitleBar(this)),
      m_displayWidget(new DisplayWidget(this)),
      m_mainWidgetVLayout(new QVBoxLayout(this))
{
    setupGui();
    initConnect();
    initGsettings();

    if (g_config_signal->m_kylinScannerImageDebug) {
        scanThreadFinishedSlot(SANE_STATUS_GOOD);
    } else {
        g_sane_object->hotplug_sock = init_hotplug_sock();
        m_detectScanDevicesThread.start();
    }
}

MainWidget::~MainWidget()
{
    g_sane_object->stopSaneRead(true);

    exit(0);
}
void MainWidget::rotationChanged(bool isPCMode,int width,int height){
    GlobalUserSignal::getInstance()->setCurrentMode(isPCMode);
    emit GlobalUserSignal::getInstance()->rotationChangedSig(isPCMode);
}
void MainWidget::setupGui()
{
    // Add window control protocol
    kabase::WindowManage::removeHeader(this);

    this->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    this->setWindowTitle(tr("Scanner"));
    this->setMouseTracking(true);
    this->setAcceptDrops(true);

    this->setObjectName("MainWindow");

    m_mainWidgetVLayout->addWidget(m_titleBar);
    m_mainWidgetVLayout->addWidget(m_displayWidget);
    m_mainWidgetVLayout->setSpacing(0);
    m_mainWidgetVLayout->setContentsMargins(0, 0, 0, 0);
    this->setLayout(m_mainWidgetVLayout);

    this->resize(MainWidgetWidth, MainWidgetHeight);
    this->setMinimumSize(MainWidgetWidth, MainWidgetHeight);

    // Center window
    QScreen *screen = QGuiApplication::primaryScreen();
    move((screen->geometry().width() - MainWidgetWidth) / 2, (screen->geometry().height() - MainWidgetHeight) / 2);
}

void MainWidget::initConnect()
{
    //三联按钮响应
    connect(g_user_signal, &GlobalUserSignal::minimumWindowSignal, this, &MainWidget::showMinimized);
    connect(g_user_signal, &GlobalUserSignal::maximumWindowSignal, this, &MainWidget::maximizeWindowSlot);
    connect(g_user_signal, &GlobalUserSignal::exitApplicationSignal, this, &MainWidget::closeWindowSlot);
    //扫描设备
    connect(m_displayWidget, &DisplayWidget::detectScanDevicesSignal, this, &MainWidget::detectScanDevicesSlot, Qt::QueuedConnection);
    connect(&m_detectScanDevicesThread, &DetectScanDevicesThread::detectScanDevicesFinishedSignal, this, &MainWidget::detectScanDeviceThreadFinishedSlot);
    connect(g_user_signal, &GlobalUserSignal::startUsbHotPlugThreadSignal, this, &MainWidget::startUsbHotPlugThreadSlot);
    //扫描过程
    connect(g_user_signal, &GlobalUserSignal::startScanOperationSignal, this, &MainWidget::startScanOperationSlot, Qt::QueuedConnection);
    connect(g_user_signal, &GlobalUserSignal::scanThreadFinishedSignal, this, &MainWidget::scanThreadFinishedSlot);
    connect(g_user_signal, &GlobalUserSignal::cancelScanning, this, &MainWidget::cancelScanningSlot);
    connect(g_user_signal, &GlobalUserSignal::closeScanDialogSignal, this, &MainWidget::closeScanDialogSlot);
    //阻止锁屏
    connect(g_user_signal, &GlobalUserSignal::dbusInhabitSignal, this, &MainWidget::dbusInhabitSlot);
    connect(g_user_signal, &GlobalUserSignal::dbusUnInhabitSignal, this, &MainWidget::dbusUnInhabitSlot);
    connect(g_user_signal, &GlobalUserSignal::warnMsgSignal,this,&MainWidget::warnMsg);
    //锁屏信号
    QDBusConnection::systemBus().connect(QString("org.freedesktop.login1"), QString("/org/freedesktop/login1"),
                                         QString("org.freedesktop.login1.Manager"), QString("PrepareForSleep"), this,
                                         SLOT(onPrepareForSleep(bool)));
    connect(g_user_signal, &GlobalUserSignal::closeUsbHotPlugThreadSignal, this, [=](){m_usbHotplugThread.exitWindowFlag = true;});
    connect(g_user_signal, &GlobalUserSignal::startHotPlugSignal, this, &MainWidget::startHotPlutSlot);
    connect(g_user_signal, &GlobalUserSignal::hotPlugScanCompleteSignal, this, [=](){g_sane_object->hotPlugScanCompleteSlot();});

    //字体，透明度改变
    connect(kdk::GsettingMonitor::getInstance(), &kdk::GsettingMonitor::systemFontSizeChange, this, &MainWidget::fontSizeChange);
    connect(kdk::GsettingMonitor::getInstance(), &kdk::GsettingMonitor::systemTransparencyChange, this, &MainWidget::transparencyChange);

    connect(g_user_signal, &GlobalUserSignal::findNoDriverDeviceSignal, this, [=](){
        m_waittingDialog = new WaittingDialog(this);
        m_waittingDialog->show();
    });
}

void MainWidget::initGsettings()
{   
    transparencyChange();
    fontSizeChange();
}

/**
 * @brief MainWidget::resizeTitleBar
 * resize Titlebar while MainWidget size have been resized
 */
void MainWidget::resizeTitleBar()
{
    m_titleBar->move(0, 0);
    m_titleBar->resize(this->width(), TitlebarHeight);
}

void MainWidget::resizeDisplayWidget()
{
    m_displayWidget->resize(this->width(), this->height() - TitlebarHeight);
}

void MainWidget::fontSizeChange()
{    
    float fontSize = kdk::GsettingMonitor::getSystemFontSize().toFloat();
    KyInfo() << "fontSize = " << fontSize;
}

void MainWidget::transparencyChange()
{
    double transparencyValue = kdk::GsettingMonitor::getSystemTransparency().toDouble();
    g_config_signal->m_transparency = transparencyValue * 255;
    this->update();
}

void MainWidget::warnMsg(QString msg)
{
    QMessageBox *msgBox = new QMessageBox();
    m_msgBoxList.append(msgBox);
    msgBox->setWindowModality(Qt::ApplicationModal);
    msgBox->setAttribute(Qt::WA_ShowModal, true);

    msgBox->setText(msg);
    msgBox->setIcon(QMessageBox::Warning);
    msgBox->setWindowTitle(tr("Scanner"));
    QPushButton *okBtn = new QPushButton(msgBox);
    okBtn->setText(tr("Ok"));
    msgBox->addButton(okBtn, QMessageBox::YesRole);
    msgBox->setContextMenuPolicy(Qt::NoContextMenu);

    QWidget *widget = nullptr;
    QWidgetList widgetList = QApplication::allWidgets();
    for (int i=0; i<widgetList.length(); ++i) {
        if (widgetList.at(i)->objectName() == "MainWindow") {
            widget = widgetList.at(i);
        }
    }
    if (widget) {
        msgBox->setParent(widget);
        QRect rect = widget->geometry();
        int x = rect.x() + rect.width()/2 - msgBox->width()/2;
        int y = rect.y() + rect.height()/2 - msgBox->height()/2;
        msgBox->move(x,y);
    }

    QTimer* timer = new QTimer();
    timer->start(20000);
    timer->setSingleShot(true);
    connect(timer, &QTimer::timeout, msgBox, &QMessageBox::accept);
    connect(msgBox, &QMessageBox::accepted, msgBox, [=](){
        if(m_msgBoxList.contains(msgBox)){
            m_msgBoxList.removeOne(msgBox);
        }
        msgBox->deleteLater();
    });

    if(m_msgBoxList.length() > 1){
        for(int i = 0; i < m_msgBoxList.length(); ++i){
            if(m_msgBoxList.at(i) != msgBox){
                m_msgBoxList.at(i)->accept();
            }
        }
    }
    msgBox->exec();
}

void MainWidget::reboot()
{
    qApp->exit(EXIT_CODE_REBOOT);
}

void MainWidget::resizeEvent(QResizeEvent *event)
{
    qDebug() << "resizeEvent 当前mode" << GlobalUserSignal::getInstance()->getCurrentMode();
    if(GlobalUserSignal::getInstance()->getCurrentMode()){
        if(this->isMaximized() || this->isFullScreen()){
            m_titleBar->updateMaxButtonStatus(true);
        }else{
            m_titleBar->updateMaxButtonStatus(false);
        }
    }else{
        m_titleBar->updateMaxButtonStatus(true);
    }

    QWidget::resizeEvent(event);
}

//void MainWidget::paintEvent(QPaintEvent *event)
//{
//    Q_UNUSED(event);

//    /* 反锯齿 */
//    QPainter p(this);
//    p.setRenderHint(QPainter::Antialiasing);

//    QPainterPath rectPath;
//    rectPath.addRoundedRect(this->rect(), 0, 0);
//    /* 开启背景模糊效果（毛玻璃） */
//    KWindowEffects::enableBlurBehind(this->winId(), true, QRegion(rectPath.toFillPolygon().toPolygon()));

//    QStyleOption opt;
//    opt.init(this);

//    p.setPen(Qt::NoPen);
//    QColor color = palette().color(QPalette::Window);
//    color.setAlpha(g_config_signal->m_transparency);
//    QPalette pal(this->palette());
//    pal.setColor(QPalette::Window,QColor(color));
//    this->setPalette(pal);
//    QBrush brush =QBrush(color);
//    p.setBrush(brush);
//    p.drawRoundedRect(opt.rect,0,0);
//    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
//    p.fillPath(rectPath, brush);
//    return;
//}
void MainWidget::keyPressEvent(QKeyEvent *event)
{
    switch (event->key()) {
    case Qt::Key_Return:
    case Qt::Key_Enter:
    case Qt::Key_Space:
        if(g_sane_object->cropFlag){
        }else{
            if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter){
                if(g_sane_object->getSaneHaveHandle()){
                    GlobalUserSignal::getInstance()->scanStart();
                }
            }
        }
        break;

    case Qt::Key_Z:
        if (event->modifiers() == Qt::ControlModifier) {
            KyInfo() << "pressed key(ctrl+z): " << event->key();
        }
        break;
    case Qt::Key_Escape:
        if (this->isFullScreen()) {
            m_titleBar->updateMaxButtonStatus(false);
            this->showNormal();
        } else {
            if (this->isMaximized()) {
                m_titleBar->updateMaxButtonStatus(false);
                this->showNormal();
            }
        }
        break;
    default:
        break;
    }
    QWidget::keyPressEvent(event);
}
void MainWidget::keyReleaseEvent(QKeyEvent *event)
{
    switch (event->key()) {
    case Qt::Key_F1:
        KyInfo() << "F1 ==========";
        showHelpDialog();
        break;
    default:
        QWidget::keyReleaseEvent(event);
        break;
    }
    return QWidget::keyReleaseEvent(event);
}

void MainWidget::closeEvent(QCloseEvent *event)
{
    event->ignore();
    m_titleBar->on_m_closeBtn_clicked();
}
void MainWidget::showHelpDialog()
{
    kdk::UserManual userManualTest;
    if (!userManualTest.callUserManual("kylin-scanner")) {
        qCritical() << "user manual call fail!";
    }
    return;
}

void MainWidget::loadAndSave(QStringList loadPath)
{
    for(int i = 0; i < loadPath.length(); i++){
        QFileInfo loadPathInfo(loadPath[i]);
        QString newLoadPath = loadPathInfo.absolutePath() + "/" + loadPathInfo.baseName() + ".jpg";
        cimg_library::CImg<unsigned char> img(QString(loadPath[i]).toLocal8Bit().data());
        if(!QFile(newLoadPath).exists()){
            img.save_jpeg(newLoadPath.toLocal8Bit().data());
        }else{
            QFile(newLoadPath).remove();
            img.save_jpeg(newLoadPath.toLocal8Bit().data());
        }
    }
}
void MainWidget::dbusInhabitSlot(){
    flag = kdk_set_inhibit_lockscreen("kylin-scanner" , "TestReason");
    if (flag == 0) {
        qCritical() << "set inhibit lock screen fail";
        return;
    }
    qDebug()<<"test result:inhabit";
}
void MainWidget::dbusUnInhabitSlot(){
    /* 取消禁止锁屏 */
    kdk_un_inhibit_lockscreen(flag);
    qDebug()<<"test result:un_inhabit";
}

void MainWidget::maximizeWindowSlot()
{
    if (this->isFullScreen()) {
        m_titleBar->updateMaxButtonStatus(false);
        this->showNormal();
    } else {
        if (this->isMaximized()) {
            m_titleBar->updateMaxButtonStatus(false);
            this->showNormal();
        } else {
            m_titleBar->updateMaxButtonStatus(true);
            this->showMaximized();
        }
    }
}
quint32 MainWidget::getWindowId(){
    return windowId;
}
void MainWidget::closeWindowSlot()
{
    exit(0);
}

void MainWidget::detectScanDevicesSlot()
{
    if (! m_detectScanDevicesThread.isRunning()) {
        KyInfo() << "Not running detect scan devices thread. Let's detect ...";
        m_detectScanDevicesThread.start();
        g_user_signal->detectPageWaitTimerStart();
    }
}

void MainWidget::detectScanDeviceThreadFinishedSlot(bool isDetected)
{
    g_user_signal->detectPageWaitTimerStop();

    if (isDetected) {
        // while detect scan device thread finished, we should open the first device to get scan parameters
        g_sane_object->openSaneDeviceForPage(0);
        m_displayWidget->showSuccessPageSlot(isDetected);
    } else {
        emit g_user_signal->findNoDriverDeviceSignal();  // 展示正在检测扫描仪模态窗口
        m_displayWidget->showFailedPageSlot();
        m_devFinder = new deviceFinder();
        QObject::connect(m_devFinder, &deviceFinder::succeed, this, &MainWidget::showNewDeviceListPageSuccessSlot);
        QObject::connect(m_devFinder, &deviceFinder::succeed, this, &MainWidget::showNewDeviceListPageFailSlot);
        m_devFinder->startWorker();
    }
}

static int getSubStringNumber(QString src, QString sub)
{
    QStringList srclist = src.split(sub);
    KyInfo() << "srclist = " << srclist
             << "srclist.size = " << srclist.size();
    return srclist.size()-1;
}



void MainWidget::startScanOperationSlot()
{
    g_sane_object->ocrFlag = 0;

    g_user_signal->exitWindowWithSaveFlag = false;

    g_sane_object->stopSaneRead(false);

    if (m_scanThread.isRunning()) {
        // complicate click scan button, will be crashed
        KyInfo() << "complicate click scan button.";
        return;
    }
    m_scanThread.start();

    showScanDialogSlot();
}

void MainWidget::showScanDialogSlot()
{
    m_scanDialog = new ScanDialog();
    m_scanDialog->setAttribute(Qt::WA_DeleteOnClose);


    QWidget *widget = nullptr;
    QWidgetList widgetList = QApplication::allWidgets();
    for (int i=0; i<widgetList.length(); ++i) {
        if (widgetList.at(i)->objectName() == "MainWindow") {
            widget = widgetList.at(i);
        }
    }
    if (widget) {
        QRect rect = widget->geometry();
        int x = rect.x() + rect.width()/2 - m_scanDialog->width()/2;
        int y = rect.y() + rect.height()/2 - m_scanDialog->height()/2;
        m_scanDialog->move(x,y);
    }

//    QPoint globalPos = this->mapToGlobal(QPoint(0, 0));
//    m_scanDialog->move(globalPos.x() + (this->width() - m_scanDialog->width())/2,
//                        globalPos.y() + (this->height() - m_scanDialog->height())/2);

    m_scanDialog->exec();
}

void MainWidget::closeScanDialogSlot()
{
    if(m_scanDialog->isVisible()){
        m_scanDialog->close();
    }
}

void MainWidget::scanThreadFinishedSlot(int saneStatus)
{
    KyInfo() << "saneStatus: " << saneStatus;

    if (saneStatus != SANE_STATUS_GOOD) {
        if (saneStatus == SANE_STATUS_INVAL) {
            warnMsg(tr("Invalid argument, please change arguments or switch other scanners."));
            qDebug() << "Invalid argument, please change arguments or switch other scanners. error code:" << QString::number(saneStatus);
        } else if (saneStatus == SANE_STATUS_EOF) {
            g_sane_object->haveScanSuccessImage = true;
            if(g_sane_object->loadFullScanFileNames.length() != 0){
                m_displayWidget->showSuccessImageHandlePageSlot();
            }
            if(cancelFlag){
                QString loadPath = g_sane_object->loadFullScanFileName;
                if(QFile::remove(loadPath)){
                    qDebug()<<"delete current image :" << loadPath <<" success!";
                }
                QString savePath = g_sane_object->saveFullScanFileName;
                if(QFile::remove(savePath)){
                    qDebug()<<"delete current image :" << savePath <<" success!";
                }
                cancelFlag = false;
                if(ThumbnailWidget::scanPictureIsEmpty){
                    emit g_user_signal->changeToConnectuccessPageSignal();
                }
            }else{
                if(g_sane_object->loadFullScanFileNames.length() != 0){
                    g_sane_object->scanPageNumber = g_sane_object->saveFullScanFileNames.length();
                    loadAndSave(g_sane_object->loadFullScanFileNames);
                    g_user_signal->scanThreadFinishedImageLoad(g_sane_object->loadFullScanFileNames, g_sane_object->saveFullScanFileNames);                   
                    ThumbnailWidget::scanPictureIsEmpty = false;
                }
            }
            qDebug() << "no more file to read!";

        } else if (saneStatus == SANE_STATUS_DEVICE_BUSY) {
            closeScanDialogSlot();
            warnMsg(tr("Device busy, please wait or switch other scanners."));
            qDebug() << "Device busy, please wait or switch other scanners. error code:" << QString::number(saneStatus);
        } else if(saneStatus == SANE_STATUS_NO_DOCS) {
            closeScanDialogSlot();
            warnMsg(tr("Document feeder out of documents, please place papers and scan again."));
            qDebug() << "Document feeder out of documents, please place papers and scan again. error code:" << QString::number(saneStatus);
        } else if(saneStatus == SANE_STATUS_CANCELLED) {
            closeScanDialogSlot();
            warnMsg(tr("Scan operation has been cancelled."));
            qDebug() << "Scan operation has been cancelled. error code:" << QString::number(saneStatus);
            cancelFlag = false;
        } else if(saneStatus == SANE_STATUS_UNSUPPORTED){
            warnMsg(tr("Scan failed, operation is not supported."));
            qDebug() << "Scan failed, operation is not supported. error code:" << QString::number(saneStatus);
        }else if(saneStatus == SANE_STATUS_JAMMED){
            warnMsg(tr("Scan failed, Document fedder jammed."));
            qDebug() << "Scan failed, Document fedder jammed. error code:" << QString::number(saneStatus);
        }else if(saneStatus == SANE_STATUS_IO_ERROR){
            warnMsg(tr("Scan failed, Error during device I/O."));
            qDebug() << "Scan failed, Error during device I/O. error code:" << QString::number(saneStatus);
        }else if(saneStatus == SANE_STATUS_NO_MEM){
            warnMsg(tr("Scan failed, Out of memory."));
            qDebug() << "Scan failed, Out of memory. error code:" << QString::number(saneStatus);
        }else if(saneStatus == SANE_STATUS_ACCESS_DENIED){
            warnMsg(tr("Scan failed, Access to resource has been denied."));
            qDebug() << "Scan failed, Access to resource has been denied. error code:" << QString::number(saneStatus);
        }else if(saneStatus == SANE_STATUS_COVER_OPEN){
            warnMsg(tr("Scan failed, Scanner cover is open."));
            qDebug() << "Scan failed, Scanner cover is open. error code:" << QString::number(saneStatus);
        }else{
            qDebug() << "met error! saneStatus:" << saneStatus;
            warnMsg(tr("Scan failed, please check your scanner or switch other scanners. If you want to continue using the scanner, click Options, refresh the list to restart the device."));
            qDebug() << "Scan failed, please check your scanner or switch other scanners. If you want to continue using the scanner, click Options, refresh the list to restart the device." << QString::number(saneStatus);
        }
    } else {
        g_sane_object->haveScanSuccessImage = true;

        m_displayWidget->showSuccessImageHandlePageSlot();
        if(cancelFlag){
            QString loadPath = g_sane_object->loadFullScanFileName;
            if(QFile::remove(loadPath)){
                qDebug()<<"delete current image :" << loadPath <<" success!";
            }
            QString savePath = g_sane_object->saveFullScanFileName;
            if(QFile::remove(savePath)){
                qDebug()<<"delete current image :" << savePath <<" success!";
            }
            cancelFlag = false;
            if(ThumbnailWidget::scanPictureIsEmpty){
                emit g_user_signal->changeToConnectuccessPageSignal();
            }
        }else{
            g_sane_object->scanPageNumber = g_sane_object->saveFullScanFileNames.length();

            loadAndSave(g_sane_object->loadFullScanFileNames);
            g_user_signal->scanThreadFinishedImageLoad(g_sane_object->loadFullScanFileNames, g_sane_object->saveFullScanFileNames);
            ThumbnailWidget::scanPictureIsEmpty = false;
        }
        // to do: update thumbtailwidget icon to current filepath
    }
}

void MainWidget::cancelScanningSlot(){
    cancelFlag = true;
    g_sane_object->stopSaneReadFlag = true;
}

void MainWidget::onPrepareForSleep(bool isSleep)
{
    if (isSleep) //睡眠分支
    {
        qDebug() << "睡眠！！！";
    } else //唤醒分支
    {
        qDebug() << "唤醒！！！";
        // 提示用户  检测到休眠/睡眠，请检测扫描仪状态，若未继续扫描，需手动点击取消或刷新列表恢复设备扫描功能
        QString msg = tr("Detected system hibernation/sleep. Please check the scanner status. If scanning does not continue, you need to manually click cancel or refresh the list to resume device scanning function.");
        g_user_signal->warnMsg(msg);
    }
}

void MainWidget::newUsbConnectedSlot()
{
    QMessageBox::information(this, tr("Alert"), tr("A new Scanner has been connected."));
}

void MainWidget::startUsbHotPlugThreadSlot()
{
    m_usbHotplugThread.exitWindowFlag = false;
    while(1){
        if(m_detectScanDevicesThread.isFinished()){
            m_usbHotplugThread.start();
            break;
        }
    }
}


void MainWidget::startHotPlutSlot()
{
    emit g_user_signal->setExitFlagFalseSignal();
    m_usbHotplugThread.start();
}

void MainWidget::showNewDeviceListPageSuccessSlot()
{
    qDebug() << "Install succeed";
    m_waittingDialog->close();
    // 初始化页面并，解析内容并展示
    m_noDriverDevices.clear();
    m_noDriverDevices = m_devFinder->getList();
    if(m_noDriverDevices.length() != 0){
        m_deviceListPage = new newDeviceListPage(m_noDriverDevices, this);
    }
    m_devFinder->finished();
}

void MainWidget::showNewDeviceListPageFailSlot()
{
    qDebug() << "Install failed";
}

void MainWidget::showBeautyRunningDialog()
{
    m_beautyRunningDialog = new RunningDialog(this, tr("Running beauty ..."));

    QPoint globalPos = this->mapToGlobal(QPoint(0, 0));
    int m_x = (this->width() - m_beautyRunningDialog->width()) / 2;
    int m_y = (this->height() - m_beautyRunningDialog->height()) / 2;

    m_beautyRunningDialog->move(globalPos.x() + m_x, globalPos.y() + m_y);

    m_beautyRunningDialog->exec();


//    g_user_signal->doBeautyOperation();
}

void MainWidget::hideBeautyRunningDialog()
{
    m_beautyRunningDialog->hide();
    m_beautyRunningDialog->reject();
}

void MainWidget::showRectifyRunningDialog()
{
    m_rectifyRunningDialog = new RunningDialog(this, tr("Running rectify ..."));

    QPoint globalPos = this->mapToGlobal(QPoint(0, 0));
    int m_x = (this->width() - m_rectifyRunningDialog->width()) / 2;
    int m_y = (this->height() - m_rectifyRunningDialog->height()) / 2;

    m_rectifyRunningDialog->move(globalPos.x() + m_x, globalPos.y() + m_y);

    m_rectifyRunningDialog->setModal(true);
    m_rectifyRunningDialog->show();

    connect(m_rectifyRunningDialog, &RunningDialog::rejected, this, &MainWidget::isRejectedRectifySlot);

    g_user_signal->doRectifyOperation();
}

void MainWidget::startRectifyOperationSlot()
{
//    QEventLoop eventLoop;
    m_rectifyThread.start();
//    connect(&m_rectifyThread, SIGNAL(finished()), &eventLoop, SLOT(quit()));
//    m_rectifyThread.wait();
    //    eventLoop.exec();
}

void MainWidget::isRejectedRectifySlot()
{
    KyInfo() << "rectify is reject.";
    if (! m_rectifyRunningDialog->isHidden()) {
        m_rectifyRunningDialog->hide();
        m_rectifyRunningDialog->reject();
    }
}

void MainWidget::hideRectifyRunningDialog(bool isTrue)
{
    KyInfo() << "hide rectify dialog";
    if (! m_rectifyRunningDialog->isHidden()) {
        m_rectifyRunningDialog->hide();
        m_rectifyRunningDialog->reject();
    }
}


void DetectScanDevicesThread::run()
{
    KyInfo() << "FindScanDevicesThread begin";

    bool res = g_sane_object->detectSaneDevices();

    if (! res) {
        emit detectScanDevicesFinishedSignal(false);
        emit g_user_signal->closeUsbHotPlugThreadSignal();
        KyInfo() << "detect scan devices finished: false.";
    } else {
        emit detectScanDevicesFinishedSignal(true);
        KyInfo() << "detect scan devices finished: true.";
        emit g_user_signal->startUsbHotPlugThreadSignal();
    }
}


void ScanThread::run()
{
    g_sane_object->isOnScanning = true;
    int ret = 0;

    g_sane_object->scanPageNumber = 0;
    g_sane_object->loadFullScanFileNames.clear();
    g_sane_object->saveFullScanFileNames.clear();

    QString pageNumber = g_sane_object->userInfo.pageNumber;

    emit g_user_signal->dbusInhabitSignal();      // 阻止扫描过程中睡眠

    KyInfo() << "start_scanning start";
    ret = g_sane_object->startScanning(g_sane_object->userInfo);
    KyInfo() << "start_scanning end, status = " << ret;

    int saneStatus = ret;

    g_user_signal->scanThreadFinished(ret);

    emit g_user_signal->dbusUnInhabitSignal();

    emit g_user_signal->cancelOprationOKSignal();
    g_sane_object->isOnScanning = false;
    quit();
}


RectifyThread::RectifyThread(QObject *parent)
    : QThread(parent)
{
    KyInfo() << "Create rectify thread.";
}

RectifyThread::~RectifyThread()
{
}

void RectifyThread::run()
{
}

void RectifyThread::rectifyThreadStop()
{
    if(isRunning())
    {
        terminate();
        wait();
    }
}
